﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace SD.App.Desktop.Repository
{
    /// <summary>
    /// 通用 Repository 接口（支持常见 CRUD）
    /// </summary>
    /// <typeparam name="T">实体类（对应数据库表）</typeparam>
    /// <typeparam name="TKey">主键类型（long/int/string 等）</typeparam>
    public interface IRepository<T, TKey> where T : class, new()
    {
        #region 新增
        /// <summary>
        /// 新增单条数据
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <returns>新增后的主键</returns>
        Task<T> AddAsync(T entity);

        /// <summary>
        /// 批量新增数据
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <returns>新增成功的条数</returns>
        Task<int> BatchAddAsync(List<T> entities);
        #endregion

        #region 删除
        /// <summary>
        /// 根据主键删除单条数据
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>删除成功的条数</returns>
        Task<int> DeleteByIdAsync(TKey id);

        /// <summary>
        /// 根据主键批量删除
        /// </summary>
        /// <param name="ids">主键集合</param>
        /// <returns>删除成功的条数</returns>
        Task<int> BatchDeleteByIdsAsync(List<TKey> ids);

        /// <summary>
        /// 根据条件删除数据（谨慎使用）
        /// </summary>
        /// <param name="whereExpression">删除条件</param>
        /// <returns>删除成功的条数</returns>
        Task<int> DeleteByConditionAsync(Expression<Func<T, bool>> whereExpression);
        #endregion

        #region 修改
        /// <summary>
        /// 全量更新单条数据（所有字段都会更新）
        /// </summary>
        /// <param name="entity">实体对象（需包含主键）</param>
        /// <returns>更新成功的条数</returns>
        Task<int> UpdateAsync(T entity);

        /// <summary>
        /// 批量全量更新
        /// </summary>
        /// <param name="entities">实体集合（需包含主键）</param>
        /// <returns>更新成功的条数</returns>
        Task<int> BatchUpdateAsync(List<T> entities);

        /// <summary>
        /// 按需更新（只更新指定字段）
        /// </summary>
        /// <param name="entity">实体对象（需包含主键）</param>
        /// <param name="updateColumns">要更新的字段表达式（如：u => new { u.Name, u.Age }）</param>
        /// <returns>更新成功的条数</returns>
        Task<int> UpdatePartialAsync(T entity, Expression<Func<T, object>> updateColumns);

        /// <summary>
        /// 按条件更新（指定条件和更新字段）
        /// </summary>
        /// <param name="whereExpression">更新条件</param>
        /// <param name="updateExpression">更新内容（如：u => new T { Name = "新名称" }）</param>
        /// <returns>更新成功的条数</returns>
        Task<int> UpdateByConditionAsync(Expression<Func<T, bool>> whereExpression, Expression<Func<T, T>> updateExpression);
        #endregion

        #region 查询
        /// <summary>
        /// 根据主键查询单条数据
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns>实体对象（无数据返回 null）</returns>
        Task<T?> GetByIdAsync(TKey id);

        /// <summary>
        /// 根据条件查询单条数据（返回第一条）
        /// </summary>
        /// <param name="whereExpression">查询条件</param>
        /// <returns>实体对象（无数据返回 null）</returns>
        Task<T?> GetFirstAsync(Expression<Func<T, bool>> whereExpression);

        /// <summary>
        /// 查询所有数据
        /// </summary>
        /// <returns>实体集合</returns>
        Task<List<T>> GetAllAsync();

        /// <summary>
        /// 根据条件查询数据列表
        /// </summary>
        /// <param name="whereExpression">查询条件（可为 null，查询所有）</param>
        /// <returns>实体集合</returns>
        Task<List<T>> GetListAsync(Expression<Func<T, bool>>? whereExpression = null);

        /// <summary>
        /// 条件查询 + 排序
        /// </summary>
        /// <param name="whereExpression">查询条件（可为 null）</param>
        /// <param name="orderExpression">排序表达式（如：u => u.CreateTime）</param>
        /// <param name="isAsc">是否升序（默认 true）</param>
        /// <returns>排序后的实体集合</returns>
        Task<List<T>> GetListOrderByAsync(Expression<Func<T, bool>>? whereExpression = null,
            Expression<Func<T, object>>? orderExpression = null, bool isAsc = true);

        /// <summary>
        /// 分页查询（基础版）
        /// </summary>
        /// <param name="pageIndex">页码（从 1 开始）</param>
        /// <param name="pageSize">每页条数</param>
        /// <param name="whereExpression">查询条件（可为 null）</param>
        /// <returns>分页结果（数据集合 + 总条数）</returns>
        Task<(List<T> Data, int TotalCount)> GetPageListAsync(int pageIndex, int pageSize,
            Expression<Func<T, bool>>? whereExpression = null);

        /// <summary>
        /// 分页查询 + 排序（进阶版）
        /// </summary>
        /// <param name="pageIndex">页码（从 1 开始）</param>
        /// <param name="pageSize">每页条数</param>
        /// <param name="whereExpression">查询条件（可为 null）</param>
        /// <param name="orderExpression">排序表达式（如：u => u.CreateTime）</param>
        /// <param name="isAsc">是否升序（默认 true）</param>
        /// <returns>分页结果（数据集合 + 总条数）</returns>
        Task<(List<T> Data, int TotalCount)> GetPageListOrderByAsync(int pageIndex, int pageSize,
            Expression<Func<T, bool>>? whereExpression = null,
            Expression<Func<T, object>>? orderExpression = null, bool isAsc = true);

        /// <summary>
        /// 检查数据是否存在
        /// </summary>
        /// <param name="whereExpression">查询条件</param>
        /// <returns>true：存在；false：不存在</returns>
        Task<bool> ExistsAsync(Expression<Func<T, bool>> whereExpression);

        /// <summary>
        /// 统计数据条数
        /// </summary>
        /// <param name="whereExpression">查询条件（可为 null，统计所有）</param>
        /// <returns>数据条数</returns>
        Task<int> CountAsync(Expression<Func<T, bool>>? whereExpression = null);
        #endregion
    }
}
